﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using Sinacor.OMM.Configuration;
using Sinacor.OMM.Configuration.OrderBovespaSystem;
using System.Threading;
using PSE.Framework.Threading;

namespace Sinacor.OMM.OrderExecutor.ProcessLogic
{
    public class OrderExecutorConfigurationManager
    {
        static Int32 _companyId;
        static string _configFile;
        static Int32 _refreshTimer;
        static OrderBovespaSystemConfiguration _orderBovespaSystemInformation;
        private static bool _shouldStopRefreshing = false;
        /// <summary>
        /// Company ID
        /// </summary>
        public static Int32 CompanyId
        {
            get 
            {
                if (_companyId.Equals(0))
                {
                    if (string.IsNullOrEmpty(_configFile))
                        _configFile = Path.Combine(Path.GetDirectoryName(System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath), "Sinacor.OMM.OrderExecutor.exe");

                    System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(_configFile);

                    if (config == null)
                        throw new ConfigurationErrorsException(string.Format("Configuration file '{0}' not found.", _configFile));

                    if (!Int32.TryParse(config.AppSettings.Settings["companyId"].Value, out _companyId))
                        throw new ConfigurationErrorsException("Configuration company id not found.");
                }

                return _companyId;
            }
        }

        /// <summary>
        /// Refresh Timer
        /// </summary>
        public static Int32 RefreshTimer
        {
            get
            {
                if (_refreshTimer.Equals(0))
                {
                    if (string.IsNullOrEmpty(_configFile))
                        _configFile = Path.Combine(Path.GetDirectoryName(System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath), "Sinacor.OMM.OrderExecutor.exe");

                    System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(_configFile);

                    if (config == null)
                        throw new ConfigurationErrorsException(string.Format("Configuration file '{0}' not found.", _configFile));

                    if (!Int32.TryParse(config.AppSettings.Settings["refreshTimer"].Value, out _refreshTimer))
                        throw new ConfigurationErrorsException("Configuration refresh timer not found.");
                }

                return _refreshTimer;
            }
        }


        /// <summary>
        /// Starts refreshing the configuration.
        /// </summary>
        public static void StartRefresh()
        {
            _shouldStopRefreshing = false;
            Thread messageReaderThread = new Thread(new ThreadStart(UpdateConfiguration));
            messageReaderThread.Start();
        }

        /// <summary>
        /// Stops refreshing the configuration.
        /// </summary>
        public static void StopRefresh()
        {
            _shouldStopRefreshing = true;
        }

        /// <summary>
        /// Update the configuration
        /// </summary>
        private static void UpdateConfiguration()
        {
            while (!_shouldStopRefreshing)
            {
                Sleeper.Sleep(1000, () => !_shouldStopRefreshing);
                BuildOrderBovespaSystemInformation();
            }
        }

        /// <summary>
        /// Order Bovespa System Information
        /// </summary>
        public static OrderBovespaSystemConfiguration OrderBovespaSystemInformation
        {
            get
            {
                try
                {
                    if (_orderBovespaSystemInformation == null)
                        BuildOrderBovespaSystemInformation();

                }
                catch (Exception ex)
                {
                    //Sinacor.OMM.Logging.Logger.WriteError(ex, Logging.LogSources.RouterService, PSE.Framework.ErrorLogging.LogOutputType.XmlFile);
                }

                return _orderBovespaSystemInformation;
            }
        }

        /// <summary>
        /// Build order Bovespa system information
        /// </summary>
        private static void BuildOrderBovespaSystemInformation()
        {
            if (_orderBovespaSystemInformation == null)
                _orderBovespaSystemInformation = new OrderBovespaSystemConfiguration();

            lock (_orderBovespaSystemInformation)
            {
                _orderBovespaSystemInformation =
                   new OrderBovespaSystemConfigurationReader(_companyId).GetOrderBovespaSystemInformation();
            }
        }

    }
}
